#pragma once

#include "Common.h"
#include "ThreadCache.h"
#include "PageCache.h"
#include "FixedLengthpool.h"

static void* ConcurrentAlloc(size_t size)
{
	assert(size);

	size_t AlignNum = ClassSize::RoundUp(size);
	size_t kpage = AlignNum >> PAGE_SHIFT;

	if (AlignNum > MAX_BYTES) // 33 + KB
	{
		std::lock_guard<std::mutex> lk(PageCache::GetInstance()->_page_mtx); // ������Ҫ�޸�page����Ҫ����
		Span* span = PageCache::GetInstance()->GetSpan(kpage);

		return (void*)(span->_pageid << PAGE_SHIFT);
	}
	else // 1 ~ 32
	{
		if (!pTLSThreadCache)
		{
			static kele::blockectPool<ThreadCache> ThreadCacheBlockPool;
			std::lock_guard<std::mutex> lk(ThreadCacheBlockPool._mtx);
			pTLSThreadCache = ThreadCacheBlockPool.New();
		}
		return pTLSThreadCache->Allocate(size);
	}

}

static void ConcurrentFree(void* ptr)
{
	assert(ptr);
	// ��Ϊ����spanֻ��������Ҫ���� ���� ��������ʱ�������߳��޸���λ�ù�ϵ�����ܻ���Ӱ��  // ���ڿ��Բ�����
	Span* span = PageCache::GetInstance()->MapBlockToSpan(ptr);
	size_t size = span->_blocksize; // size�Ƕ�����

	if (size > MAX_BYTES) // 33 + KB
	{
		std::lock_guard<std::mutex> lk(PageCache::GetInstance()->_page_mtx); // ��

		span->_isUse = false;
		span->_usecount = 0;
		PageCache::GetInstance()->ReleaseSpanToPageCache(span); 
	}
	else // 1 ~ 32
	{
		assert(pTLSThreadCache);
		pTLSThreadCache->Deallocate(ptr, size);
	}

}